package org.snusmumr.android.media.tools;

import java.io.IOException;
import java.util.ArrayList;

import org.snusmumr.android.media.R;
import org.snusmumr.android.media.bean.ItemModel;
import org.snusmumr.android.media.bean.LabelModel;
import org.snusmumr.android.media.data.DatabaseProvider;
import org.snusmumr.android.media.data.DatabaseProvider.DatabaseMode;
import org.snusmumr.android.media.data.MediaColumns;
import org.snusmumr.android.media.data.SaveMediaItemOperation;
import org.snusmumr.android.media.event.Event;
import org.snusmumr.android.media.event.IObservable;
import org.snusmumr.android.media.event.IObserver;
import org.snusmumr.android.media.event.ImportEvent;
import org.snusmumr.android.media.event.ObservableImpl;
import org.snusmumr.android.media.util.Utils;

import android.app.AlertDialog;
import android.content.Context;
import android.content.DialogInterface;
import android.content.DialogInterface.OnClickListener;
import android.content.res.Resources;
import android.database.Cursor;
import android.database.sqlite.SQLiteDatabase;
import android.util.Log;

public class Importer implements IObservable {
	private static final String TAG = Importer.class.getSimpleName();
	
	private ObservableImpl observable;
	private Context context;
	private ArrayList<ItemModel<String>> categories;
	private ArrayList<LabelModel> labels;
	private ArrayList<ModelAuthor> authors;

	private SQLiteDatabase dataBase;
	
	
	public Importer(Context context) {
		this.context = context;
		this.observable = new ObservableImpl();
	}
	
	private void init() {
		dataBase = DatabaseProvider.getInstance(context).getDatabase(DatabaseMode.Write);
		final Resources res = context.getResources();
		
		// get authors
		Cursor cur = dataBase.rawQuery(res.getString(R.string.sql_fetch_authors), new String[]{});
		authors = new ArrayList<ModelAuthor>(cur.getCount());
		cur.moveToFirst();
		int indexName = cur.getColumnIndex(MediaColumns.NAME);
		int indexId = cur.getColumnIndex(MediaColumns._ID);
        while (cur.isAfterLast() == false) {
            String name = cur.getString(indexName);
            Long id = cur.getLong(indexId);
            authors.add(new ModelAuthor(name, id));
       	    cur.moveToNext();
        }
        cur.close();
		
		// get categories
        cur = dataBase.rawQuery(res.getString(R.string.sql_fetch_categories), new String[]{});
		categories = new ArrayList<ItemModel<String>>(cur.getCount());
		cur.moveToFirst();
		indexName = cur.getColumnIndex(MediaColumns.NAME);
		indexId = cur.getColumnIndex(MediaColumns._ID);
        while (cur.isAfterLast() == false) {
            String name = cur.getString(indexName);
            Long id = cur.getLong(indexId);
            categories.add(new ItemModel<String>(id, name));
       	    cur.moveToNext();
        }
        cur.close();
        
		// get labels
        cur = dataBase.rawQuery(res.getString(R.string.sql_fetch_labels), new String[]{});
		labels = new ArrayList<LabelModel>(cur.getCount());
		cur.moveToFirst();
		indexName = cur.getColumnIndex(MediaColumns.NAME);
		indexId = cur.getColumnIndex(MediaColumns._ID);
		int indexColor = cur.getColumnIndex(MediaColumns.COLOR);
        while (cur.isAfterLast() == false) {
            String name = cur.getString(indexName);
            Long id = cur.getLong(indexId);
            Integer color = cur.getInt(indexColor);
            labels.add(new LabelModel(id, name, color));
       	    cur.moveToNext();
        }
        cur.close();
        
        // notify observers
        notifyObservers(new ImportEvent("Import initialized", 10d));
	}
	
	public void releaseResources() {
		dataBase.close();
		Utils.releaseList(authors);
		Utils.releaseList(categories);
		Utils.releaseList(labels);
	}
	
	public boolean doImport(String fileName) {
		init();
		
		ImportParser parser = new ImportParser(fileName);
		ModelItem item = null;
		try {
			while((item = parser.next()) != null) {
				Log.i(TAG, "processing line " + parser.getReadLine());
				dataBase.beginTransaction();
				ModelAuthor author = item.getAuthor();
				long authorId = importAuthor(author);
				long categoryId = importCategory(item.getCategory());
				ArrayList<Long> labels = importLabels(item.getLabels());
				
				
				//save and end transaction
				dataBase.setTransactionSuccessful();
				dataBase.endTransaction();
			}
		} catch (IOException e) {
			Log.e(TAG, "Error at importing media items", e);
//			TODO show error
//			showError(resId);
			return false;
		} catch (InvalidStorageStateException e) {
//			TODO show error
//			showError(resId);
			return false;
		} catch (InvalidFileFormatException e) {
			showError(getErrorMessageByCode(e.getErrorCode()));
			return false;
		} catch (ParseException e) {
			// TODO Auto-generated catch block
			e.printStackTrace();
		} finally {
			try {
				parser.close();
			} catch (IOException e) {
				e.printStackTrace();
			}
		}
		return true;
	}
	
	private ArrayList<Long> importLabels(ModelLabel[] labels2) {
		// TODO Auto-generated method stub
		return null;
	}

	private long importAuthor(ModelAuthor author) {
		// TODO Auto-generated method stub
		return 0;
	}

	private long importCategory(String category) {
		// TODO Auto-generated method stub
		return 0;
	}

	private String getErrorMessageByCode(int code) {
		switch (code) {
		case InvalidFileFormatException.ERROR_IMPORT_FILE_EMPTY:
			return context.getResources().getString(R.string.msg_err_import_file_empty);

		default:
			break;
		}
		return "";
	}
	
	private void showError(int resId) {
		AlertDialog.Builder builder = new AlertDialog.Builder(context);
		builder.setIcon(android.R.drawable.ic_dialog_alert)
		.setMessage(resId).setTitle(R.string.msg_err_import_failed)
		.setPositiveButton(android.R.string.ok, new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.cancel();
			}
		}).show();
	}
	
	private void showError(String message) {
		AlertDialog.Builder builder = new AlertDialog.Builder(context);
		builder.setIcon(android.R.drawable.ic_dialog_alert)
		.setMessage(message).setTitle(R.string.msg_err_import_failed)
		.setPositiveButton(android.R.string.ok, new OnClickListener() {
			@Override
			public void onClick(DialogInterface dialog, int which) {
				dialog.cancel();
			}
		}).show();
	}

	@Override
	public void register(IObserver observer) {
		observable.register(observer);
	}

	@Override
	public void unRegister(IObserver observer) {
		observable.unRegister(observer);
	}

	@Override
	public void notifyObservers(Event e) {
		observable.notifyObservers(e);
	}
}
